package goxpath

import (
	
	

	
	
	
)

//Opts defines namespace mappings and custom functions for XPath expressions.
type Opts struct {
	NS    map[string]string
	Funcs map[xml.Name]tree.Wrap
	Vars  map[string]tree.Result
}

//FuncOpts is a function wrapper for Opts.
type FuncOpts func(*Opts)

//XPathExec is the XPath executor, compiled from an XPath string
type XPathExec struct {
	n *parser.Node
}

//Parse parses the XPath expression, xp, returning an XPath executor.
func ( string) (XPathExec, error) {
	,  := parser.Parse()
	return XPathExec{n: }, 
}

//MustParse is like Parse, but panics instead of returning an error.
func ( string) XPathExec {
	,  := Parse()
	if  != nil {
		panic()
	}
	return 
}

//Exec executes the XPath expression, xp, against the tree, t, with the
//namespace mappings, ns, and returns the result as a stringer.
func ( XPathExec) ( tree.Node,  ...FuncOpts) (tree.Result, error) {
	 := &Opts{
		NS:    make(map[string]string),
		Funcs: make(map[xml.Name]tree.Wrap),
		Vars:  make(map[string]tree.Result),
	}
	for ,  := range  {
		()
	}
	return execxp.Exec(.n, , .NS, .Funcs, .Vars)
}

//ExecBool is like Exec, except it will attempt to convert the result to its boolean value.
func ( XPathExec) ( tree.Node,  ...FuncOpts) (bool, error) {
	,  := .Exec(, ...)
	if  != nil {
		return false, 
	}

	,  := .(tree.IsBool)
	if ! {
		return false, fmt.Errorf("Cannot convert result to a boolean")
	}

	return bool(.Bool()), nil
}

//ExecNum is like Exec, except it will attempt to convert the result to its number value.
func ( XPathExec) ( tree.Node,  ...FuncOpts) (float64, error) {
	,  := .Exec(, ...)
	if  != nil {
		return 0, 
	}

	,  := .(tree.IsNum)
	if ! {
		return 0, fmt.Errorf("Cannot convert result to a number")
	}

	return float64(.Num()), nil
}

//ExecNode is like Exec, except it will attempt to return the result as a node-set.
func ( XPathExec) ( tree.Node,  ...FuncOpts) (tree.NodeSet, error) {
	,  := .Exec(, ...)
	if  != nil {
		return nil, 
	}

	,  := .(tree.NodeSet)
	if ! {
		return nil, fmt.Errorf("Cannot convert result to a node-set")
	}

	return , nil
}

//MustExec is like Exec, but panics instead of returning an error.
func ( XPathExec) ( tree.Node,  ...FuncOpts) tree.Result {
	,  := .Exec(, ...)
	if  != nil {
		panic()
	}
	return 
}

//ParseExec parses the XPath string, xpstr, and runs Exec.
func ( string,  tree.Node,  ...FuncOpts) (tree.Result, error) {
	,  := Parse()
	if  != nil {
		return nil, 
	}
	return .Exec(, ...)
}